package cate.game.notice;

import cate.common.table.text.TextLampRow;
import cate.common.util.GameResult;
import cp.solution.business.game.component.NoticeParam;
import cate.game.GameBody;
import cate.game.chat.ChatContentParam;
import cate.game.chat.ChatFacade;
import cate.game.framework.ModuleMan;
import cate.game.framework.ThreadShare;
import cate.game.notice.msg.NoticeDialogResp;
import cate.game.notice.msg.NoticeLampResp;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.res.RewardShow;
import cate.game.role.Role;
import easy.java.practice.errorcode.EcResult;
import easy.java.util.StrTool;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/** 通知模块管理 */
public class NoticeManager extends ModuleMan {
    @Override
    public void initIndependent(GameBody game) throws Exception {
        super.initIndependent(game);
    }

    @Override
    public void initDependent() throws Exception {

    }

    public void message(Role role, EcResult r) {
        message(role, r, false);
    }

    public void message(Role role, GameResult r){
        message(role, r, false);
    }

    public void message(Role role, Exception e) {
        message(role, e.getMessage());
    }

    /**
     * 简单消息
     *
     * @param onlyWhenFail 仅当失败时才发送消息
     */
    public void message(Role role, EcResult r, boolean onlyWhenFail) {
        boolean send = true;
        if (onlyWhenFail && r.ok()) {
            send = false;
        }
        if (send) {
            message(role, r.message);
        }
    }

    public void message(Role role, GameResult r, boolean onlyWhenFail) {
        boolean send = true;
        if (onlyWhenFail && r.ok()) {
            send = false;
        }
        if (send) {
            message(role, r.contentId, r.message, r.paramList);
        }
    }

    /** 简单消息 */
    public void message(Role role, String content) {
        message(role, 0, content, (List) null);
    }

    public void message(Role role, int contentId, String defaultContent){
        message(role, contentId, defaultContent, (List) null);
    }

    public void message(Role role, int contentId, String defaultContent, Object param){
        message(role, contentId, defaultContent, param == null ? null : new Object[]{param});
    }

    public void message(Role role, int contentId, String defaultContent, Object[] args){
        if (contentId == 0 && StringUtils.isBlank(defaultContent)) {
            return;
        }
        List<Object> paramList = new ArrayList<>();
        if(contentId == 0){
            paramList.add(new NoticeParam(StrTool.format(defaultContent, args)));
        }else if(ArrayUtils.isNotEmpty(args)){
            NoticeParam[] params = new NoticeParam[args.length];
            for(int i=0; i<args.length; ++i){
                if(args[i] instanceof NoticeParam){
                    params[i] = (NoticeParam) args[i];
                }else{
                    params[i] = new NoticeParam(args[i]);
                }
            }
            paramList.addAll(Arrays.asList(params));
        }
        role.sendNow(new MessageRespBuilder().contentId(contentId).paramList(paramList.isEmpty() ? null : paramList).build());
    }

    public void message(Role role, int contentId, String defaultContent, List<Object> args){
        Object[] arr = null;
        if(CollectionUtils.isNotEmpty(args)){
            arr = args.toArray();
        }
        message(role, contentId, defaultContent, arr);
    }

    /** 对话：获得奖励 */
    public void dialogReward(Role role, MixRes reward) {
        if (!reward.isEmpty()) {
            RewardShow rs = new RewardShow();
            for (MixResItem mixResItem : reward.items) {
                if (mixResItem.instance != null) {
                    rs.addInsRwd(mixResItem.instance.type, mixResItem.instance.uid);
                } else {
                    rs.addTplItem(mixResItem);
                }
            }
            dialog(role, NoticeDialogResp.TYPE_REWARD, "恭喜获得", 0, null, rs.tplRwd, rs.insRwd);
        }
    }

    /** 对话 */
    public void dialog(Role role, byte type, String title, String content, MixRes reward) {
        List<Object> paramList = new ArrayList<>();
        paramList.add(content);
        dialog(role, type, title, 0, paramList, reward);
    }

    /** 对话 */
    public void dialog(Role role, byte type, String title, int contentId, List<Object> paramList, MixRes reward) {
        dialog(role,type,title,contentId,paramList,reward,null);
    }

    /** 对话:带有实例数据 */
    public void dialog(Role role, byte type, String title, int contentId, MixRes reward, Map<Byte, List<String>> instanceMap) {
        dialog(role,type,title,contentId,null,reward,instanceMap);
    }

    public void dialog(Role role, RewardShow rewardShow) {
        dialog(role, NoticeDialogResp.TYPE_REWARD, "恭喜获得", 0, null, rewardShow.tplRwd, rewardShow.insRwd);
    }

    /** 对话 */
    public void dialog(Role role, byte type, String title, int contentId, List<Object> paramList, MixRes reward,Map<Byte, List<String>> instanceMap ) {
        role.sendNow(new DialogRespBuilder()
                .type(type)
                .title(title)
                .contentId(contentId)
                .paramList(paramList)
                .reward(reward)
                .instanceMap(instanceMap)
                .build());
    }

    /** 提示资源获取途径 */
    public void tipResItem(Role role, MixResItem item) {
        if (item == null) {
            return;
        }
        role.sendNow(new TipResItemRespBilder().item(item).build());
    }

    private long lastNoticeAllTime = 0;
    private static final int NOTICE_ALL_TRIGGER = 3000;
    /** 向所有在线玩家发送跑马灯 */
    public void lampOnline(Role role, int contentId, List<ChatContentParam> paramList) {
        boolean noticeSelf = ThreadShare.almostFull() || lastNoticeAllTime + NOTICE_ALL_TRIGGER > System.currentTimeMillis();
        if (contentId > 0) {
            TextLampRow tlr = game.table.text.lamp.get(contentId);
            boolean needSendSystem = tlr == null || tlr.sendSystemChannel;
            if (needSendSystem) {
                ChatFacade.sendSystemAsSystem(role, game, contentId, paramList, noticeSelf);
            }
            boolean needSendGuild = tlr == null || tlr.sendGuildChannel;
            if (needSendGuild) {
                if(role == null){
                    ChatFacade.sendGuildAsSystem(game, contentId, paramList);
                }else{
                    ChatFacade.sendGuildAsMemberId(role, contentId, paramList);
                }
            }
            boolean needSendWorld = tlr == null || tlr.sendWorldChannel;
            if (needSendWorld) {
                ChatFacade.sendWorldAsSystem(game, contentId, paramList);
            }
            boolean needSendCross = tlr == null || tlr.sendCrossChannel;
            if (needSendCross) {
                ChatFacade.sendCrossAsSystem(game, contentId, paramList);
            }
        }
        NoticeLampResp lampResp = new LampRespBuilder().contentId(contentId).paramList(paramList).build();
        if(noticeSelf){
            if(role != null){
                role.sendNow(lampResp);
            }
            return;
        }
        lastNoticeAllTime = System.currentTimeMillis();
        game.role.activeForOnlineSelfThread(m -> m.sendNow(lampResp));
    }
}
